'use strict';
//设置主题、modern
joint.setTheme('material');

var toolbarHeight = 50;
//画板
var graph = new joint.dia.Graph;
//画布
var paper = new joint.dia.Paper({
    el: document.getElementById('paper'),
    model: graph,
    // width: '500px',
    // height: '300px',
    width: '100%',
    height: 'calc(100% - ' + toolbarHeight + 'px)',
    gridSize: 10,
    background: { color: '#f6f6f6' },
    magnetThreshold: 'onleave',
    moveThreshold: 5,
    clickThreshold: 5,
    linkPinning: false,
    sorting: joint.dia.Paper.sorting.APPROX,
    interactive: {
        linkMove: false,
        elementMove: false
    },
    markAvailable: true,
    snapLinks: { radius: 40 },
    defaultRouter: {
        name: 'mapping',
        args: { padding: 30 }
    },
    defaultConnectionPoint: { name: 'anchor' },
    defaultAnchor: { name: 'mapping' },
    defaultConnector: {
        name: 'jumpover',
        args: { jump: 'cubic' }
    },
    highlighting: {
        magnetAvailability: {
            name: 'addClass',
            options: {
                className: 'record-item-available'
            }
        },
        connecting: {
            name: 'stroke',
            options: {
                padding: 8,
                attrs: {
                    'stroke': 'none',
                    'fill': '#7c68fc',
                    'fill-opacity': 0.2
                }
            }
        }
    },
    defaultLink: function() {
        return new joint.shapes.mapping.Link();
    },
    //验证连接
    validateConnection: function(sv, sm, tv, tm, end) {
        if (sv === tv) return false;
        if (sv.model.isLink() || tv.model.isLink()) return false;
        if (end === 'target') return tv.model.getItemSide(tv.findAttribute('item-id', tm)) !== 'right';
        return sv.model.getItemSide(sv.findAttribute('item-id', sm)) !== 'left';
    }
});

//命令管理器
var commandManager = new joint.dia.CommandManager({
    graph: graph
});

var toolbar = new joint.ui.Toolbar({
    autoToggle: true, //自动切换
    tools: ['undo', 'redo'], //['撤销'，'重做']
    references: {
        commandManager: commandManager
    }
});

toolbar.render();
toolbar.el.style.height = toolbarHeight + 'px';
//document.body.appendChild(toolbar.el);
// 事件api:https://resources.jointjs.com/docs/jointjs/v2.2/joint.html#dia.Paper.events
//交互
//当指针进入链接上方的区域时触发。
paper.on('link:mouseenter', function(linkView) {
    this.removeTools();
    showLinkTools(linkView);
});
//当指针离开链接上方的区域时触发。
paper.on('link:mouseleave', function() {
    this.removeTools();
});

//在元素磁铁上双击指针时触发。
paper.on('element:magnet:pointerdblclick', function(elementView, evt, magnet) {
    evt.stopPropagation();
    itemEditAction(elementView.model, elementView.findAttribute('item-id', magnet));
});
//当指针在元素上单击鼠标右键时触发。
paper.on('element:contextmenu', function(elementView, evt) {
    var tools = elementView.model.getTools();
    if (tools) {
        evt.stopPropagation();
        elementActionPicker(elementView.el, elementView, tools);
    }
});
//在元素磁铁上右键单击指针时触发。
paper.on('element:magnet:contextmenu', function(elementView, evt, magnet) {
    var itemId = elementView.findAttribute('item-id', magnet);
    var tools = elementView.model.getItemTools(itemId);
    if (tools) {
        evt.stopPropagation();
        itemActionPicker(magnet, elementView, elementView.findAttribute('item-id', magnet), tools);
    }
});
//在元素上单击指针时触发。
paper.on('element:pointerclick', function(elementView) {
    showElementTools(elementView);
});
//当指针移动到元素上时触发。
paper.on('element:pointermove', function(view, evt, x, y) {
    var data = evt.data;
    var ghost = data.ghost;
    if (!ghost) {
        var position = view.model.position();
        ghost = view.vel.clone();
        ghost.attr('opacity', 0.3);
        ghost.appendTo(this.viewport);
        evt.data.ghost = ghost;
        evt.data.dx = x - position.x;
        evt.data.dy = y - position.y;
    }
    ghost.attr('transform', 'translate(' + [x - data.dx, y - data.dy] + ')');
});
//在元素上释放指针时触发。
paper.on('element:pointerup', function(view, evt, x, y) {
    var data = evt.data;
    if (data.ghost) {
        data.ghost.remove();
        view.model.position(x - data.dx, y - data.dy);
    }
});
//判断是新增链接，还是修改
var isAddList = true;
//当链路连接到小区时触发。
paper.on('link:connect', function(linkView, evt, elementViewConnected, magnet) {
    //console.log(linkView.sourceView.model.attributes.items[0][0].items);
    var inOperatorId = linkView.sourceView.model.attributes.items[0][0].id;
    var inOperatorName = linkView.sourceView.model.attributes.items[0][0].label;
    var inParamId = linkView.model.attributes.source.port;
    //var inParamName = null;

    var outOperatorId = linkView.targetView.model.attributes.items[0][0].id;
    var outOperatorName = linkView.targetView.model.attributes.items[0][0].label;
    var outParamId = linkView.model.attributes.target.port;
    //var outParamName = null;

    //var eleItem = linkView.sourceView.model.attributes.items[0][0].items;

    var addOperator = {
        // inRootParamId: inRootParamId,
        // inRootParamName: inRootParamName,
        inOperatorId: inOperatorId,
        inOperatorName: inOperatorName,
        inParamId: inParamId,
        //inParamName: inParamName,
        // outRootParamId: outRootParamId,
        // outRootParamName: outRootParamName,
        outOperatorId: outOperatorId,
        outOperatorName: outOperatorName,
        outParamId: outParamId,
        //outParamName: outParamName,
    };
    //linkChange("Add", addOperator);
    //新增链接
    if (isAddList) {
        linkChange("Add", addOperator);
    }
    isAddList = true;
});
//当链路与小区断开时触发。貌似检测不到
paper.on('link:disconnect', function(linkView, evt, elementViewDisconnected, magnet) {
    console.log(elementViewDisconnected);
    //修改链接
    //linkChange("Change", linkView.model.attributes.source.port, linkView.model.attributes.target.port);
    isAddList = false;
});
//当指针在链接上释放时触发。
// paper.on('link:pointerup', function(cellView, evt, x, y) {
//     console.dir(cellView);
// });
paper.on('element:pointerclick', function(cellView, evt, x, y) {});
paper.on('cell:pointerclick', function(cellView, evt, x, y) {});
// paper.on('element:pointerdown', function(cellView, evt, x, y) {
//     console.log(cellView);
// });
// paper.on('cell:pointerdown', function(cellView, evt, x, y) {
//     console.log(cellView);
//     if (cellView.model.attributes.type == "mapping.Link") {
//         if (cellView.model.attributes.source.port == cellView.sourceView.model.attributes.items[0][0].id) {
//             return;
//         }
//     }
// });
paper.on('element:pointerup', function(cellView, evt, x, y) {});
paper.on('cell:pointerup', function(cellView, evt, x, y) {
    if (cellView.model.attributes.type == "mapping.Link") {
        if (cellView.sourceView) {
            if (cellView.model.attributes.source.port == cellView.sourceView.model.attributes.items[0][0].id) {
                cellView.model.remove();
            }
        }
        if (cellView.targetView) {
            if (cellView.model.attributes.target.port == cellView.targetView.model.attributes.items[0][0].id) {
                cellView.model.remove();
            }
        }
    }
});
//与磁铁目标(端口)互动时触发。
// paper.on('element:magnet:pointerclick', function(elementView, evt, magnetSVGElement, x, y) {
//     console.log(elementView);
// });

function showElementTools(elementView) {
    var element = elementView.model;
    var transform = new joint.ui.FreeTransform({
        cellView: elementView,
        allowRotation: false
    });
    transform.render();
    transform.listenTo(element, 'change', updateMinSize);
    updateMinSize();

    function updateMinSize() {
        var minSize = element.getMinimalSize();
        transform.options.minHeight = minSize.height;
        transform.options.minWidth = minSize.width;
    }
}

function showLinkTools(linkView) {
    // console.log(linkView.model.attributes.source.port);
    // console.log(linkView.model.attributes.target.port);
    console.log(linkView);
    //var map = {};
    // map[linkView.model.attributes.source.port] = linkView.sourceView.model.attributes.items[0][0].id;
    // map[linkView.model.attributes.target.port] = linkView.targetView.model.attributes.items[0][0].id;
    var linkInfo = {
        sourcePort: linkView.model.attributes.source.port,
        sourceOperatorId: linkView.sourceView.model.attributes.items[0][0].id,
        targetPort: linkView.model.attributes.target.port,
        targetOperatorId: linkView.sourceView.model.attributes.items[0][0].id,
    }

    var tools = new joint.dia.ToolsView({
        tools: [
            new joint.linkTools.mapping.SourceArrowhead(),
            new joint.linkTools.mapping.TargetArrowhead(),
            new joint.linkTools.mapping.Remove({
                distance: '50%',
                action: function() {
                    linkAction(this.model, linkInfo);
                }
            }),
        ]
    });
    linkView.addTools(tools);

    //添加监听事件
    // linkView.prototype.addEventListener = function(e) {
    //     return e;
    // };
    //console.log(linkView._listeningTo);

    // linkView.el.addEventListener("change", function(e) {
    //     console.log(e);
    // });
}

function itemActionPicker(target, elementView, itemId, tools) {

    var element = elementView.model;
    var toolbar = new joint.ui.ContextToolbar({
        target: target,
        padding: 5,
        vertical: true,
        tools: tools
    });

    toolbar.render();
    toolbar.on({
        'action:remove': function() {
            element.startBatch('item-remove');
            element.removeItem(itemId);
            element.removeInvalidLinks();
            element.stopBatch('item-remove');
            toolbar.remove();
        },
        'action:edit': function() {
            toolbar.remove();
            itemEditAction(element, itemId);
        },
        'action:add-child': function() {
            toolbar.remove();
            element.addItemAtIndex(itemId, Infinity, element.getDefaultItem());
            if (element.isItemCollapsed(itemId)) element.toggleItemCollapse(itemId);
        },
        'action:add-next-sibling': function() {
            toolbar.remove();
            element.addNextSibling(itemId, element.getDefaultItem());
        },
        'action:add-prev-sibling': function() {
            toolbar.remove();
            element.addPrevSibling(itemId, element.getDefaultItem());
        }
    });
}

function elementActionPicker(target, elementView, tools) {
    var element = elementView.model
    var toolbar = new joint.ui.ContextToolbar({
        target: target,
        padding: 5,
        vertical: true,
        tools: tools
    });
    toolbar.render();
    toolbar.on({
        'action:remove': function() {
            //将删除的算子移除出参算子数组
            var id = getQueryParameter("key");
            var operatorInfo = {};
            $.ajax({
                url: 'http://192.168.60.5:8700/define/rest/param-rule/' + id.replaceAll("\"", ""),
                type: "GET",
                async: false,
                success: function(res) {
                    operatorInfo = res;
                    res.outOperatorIds.remove(element.attributes.items[0][0].id);
                    res.outOperatorNames.remove(element.attributes.items[0][0].label);
                    operatorInfo.outOperatorIds = res.outOperatorIds;
                    operatorInfo.outOperatorNames = res.outOperatorNames;
                    $.ajax({
                        url: 'http://192.168.60.5:8700/define/rest/param-rule',
                        data: JSON.stringify(operatorInfo),
                        type: "POST",
                        async: false,
                        contentType: 'application/json;charset=utf-8',
                        dataType: "json",
                        success: function(res) {
                            toolbar.remove();
                            element.remove();
                        },
                        error: function(ex) {
                            alert("移除失败！");
                        }
                    });
                },
                error: function(ex) {
                    alert(ex.responseJSON);
                },
            });
        },
        'action:add-item': function() {
            toolbar.remove();
            element.addItemAtIndex(0, Infinity, element.getDefaultItem());
        }
    });
}

function itemEditAction(element, itemId) {

    var config = element.getInspectorConfig(itemId);
    if (!config) return;

    var inspector = new joint.ui.Inspector({
        cell: element,
        live: false,
        inputs: joint.util.setByPath({}, element.getItemPathArray(itemId), config)
    });

    inspector.render();
    inspector.el.style.position = 'relative';
    inspector.el.style.overflow = 'hidden';

    var dialog = new joint.ui.Dialog({
        width: 300,
        title: 'Edit Item',
        closeButton: false,
        content: inspector.el,
        buttons: [{
            content: 'Cancel',
            action: 'cancel'
        }, {
            content: '<span style="color:#fe854f">Change</span>',
            action: 'change'
        }]
    });

    dialog.open();
    dialog.on({
        'action:cancel': function() {
            inspector.remove();
            dialog.close();
        },
        'action:change': function() {
            inspector.updateCell();
            inspector.remove();
            dialog.close();
        }
    });

    var input = inspector.el.querySelector('[contenteditable]');
    var selection = window.getSelection();
    var range = document.createRange();
    range.selectNodeContents(input);
    selection.removeAllRanges();
    selection.addRange(range);
}

function linkAction(link, linkInfo) {
    link.remove();
    linkChange("Delete", linkInfo);
}
//链接改变
function linkChange(type, addOperatorInfo) {
    console.log(JSON.stringify(addOperatorInfo));
    if (type == "Add") {
        $.ajax({
            url: 'http://192.168.60.5:8700/define/rest/param-rule/detail/',
            type: "POST",
            data: JSON.stringify(addOperatorInfo),
            async: false,
            dataType: "json",
            contentType: "application/json",
            success: function(res) {
                console.log("上传成功" + res)
            },
            error: function(ex) {
                console.log("上传失败" + ex);
            }
        })
    }
    if (type == "Delete") {
        $.ajax({
            url: 'http://192.168.60.5:8700/define/rest/param-rule/detail/',
            type: "POST",
            data: JSON.stringify(addOperatorInfo),
            async: false,
            dataType: "json",
            contentType: "application/json",
            success: function(res) {
                console.log("上传成功" + res)
            },
            error: function(ex) {
                console.log("上传失败" + ex);
            }
        })
    }
    // console.dir(graph);
    // console.log(graph.getElements());
    // console.log(graph.toJSON());

    // console.log(graph.getConnectedLinks(graph.getElements()));
    // console.log(graph.getLinks());
    // console.log(graph.getSources());
}

$("#saveInfo").on('click', function() {
    var operatorContent = {};
    var id = getQueryParameter("key");
    $.ajax({
        url: 'http://192.168.60.5:8700/define/rest/param-rule/' + id.replaceAll("\"", ""),
        type: "GET",
        async: false,
        success: function(res) {
            operatorContent = res;
        },
        error: function(ex) {
            //alert(ex.responseJSON);
        },
    });
    //获取画板上内容
    var graphEle = graph.toJSON().cells;
    //console.log(graphEle);
    // console.log(graph.toJSON());
    // console.log(graph.getLinks());
    // console.log(graph.getSources());
    //定义一个类，用于保存元素
    var graphData = {
        Record: [],
        Link: [],
    };
    if (graphEle.length > 0) {
        for (var i = 0; i < graphEle.length; i++) {
            if (graphEle[i].type == "mapping.Link") {
                graphData.Link.push(graphEle[i]);
            }
            if (graphEle[i].type == "mapping.Record") {
                var map = {};
                map.eid = graphEle[i].id;
                map.items = graphEle[i].items[0];
                map.position = graphEle[i].position;
                graphData.Record.push(map);
            }
        };
    }
    // console.log(graphData);
    // console.log();
    // var jsonString = JSON.stringify(graph.toJSON());
    // console.log(jsonString);
    // console.log(graph);
    //保存到数据库

    operatorContent.content = JSON.stringify(graphData);
    $.ajax({
        url: 'http://192.168.60.5:8700/define/rest/param-rule',
        data: JSON.stringify(operatorContent),
        type: "POST",
        async: false,
        contentType: 'application/json;charset=utf-8',
        dataType: "json",
        success: function(res) {
            alert("保存成功！");
        },
        error: function(ex) {
            alert("保存失败！");
        }
    });
});